package com.whisperarts.financer.app.editors;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import com.whisperarts.financer.app.Application;
import com.whisperarts.financer.app.utils.DateUtils;
import com.whisperarts.financer.app.utils.Icons;
import com.whisperarts.financer.model.transaction.Transaction;

public class TransactionsEditor extends EditorPart {

	public static String ID = "com.whisperarts.financer.app.editors.transactions";
//	private FormToolkit toolkit;
	private TableViewer viewer;
	private MyViewerComparator comparator;
	private CategoryFilter filter;
	private final int rowNum = 1;
	private Menu headerMenu;
	private Menu tableMenu;

	//	private static final Image CHECKED = Activator.getImageDescriptor(
	//	"icons/checked.gif").createImage();
	//private static final Image UNCHECKED = Activator.getImageDescriptor(
	//	"icons/unchecked.gif").createImage();

	public TransactionsEditor() {
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		// TODO Auto-generated method stub		
	}

	@Override
	public void doSaveAs() {
		// TODO Auto-generated method stub

	}

	@Override
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		setSite(site);
		setInput(input);
		setPartName(getAccountName());
	}

	private String getAccountName() {
		return ((AccountEditorInput) getEditorInput()).getName();
	}

	@Override
	public boolean isDirty() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isSaveAsAllowed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void createPartControl(Composite parent) {
		FormToolkit toolkit = new FormToolkit(parent.getDisplay());
		Form form = toolkit.createForm(parent);
		// Lets make a layout for the first section of the screen
		GridLayout layout = new GridLayout(1, false);
		layout.numColumns = 1;
		layout.marginWidth = 2;
		layout.marginHeight = 2;
		form.getBody().setLayout(layout);
		

		viewer = new TableViewer(form.getBody(), SWT.MULTI | SWT.H_SCROLL
				| SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
		createColumns(parent, viewer);
		final Table table = viewer.getTable();
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		initTableMenu();
		table.addListener(SWT.MenuDetect, new Listener() {
			@Override
			public void handleEvent(Event event) {
				Point pt = getSite().getWorkbenchWindow().getShell().getDisplay().map(null, table, new Point(event.x, event.y));
				Rectangle clientArea = table.getClientArea();
				boolean header = clientArea.y <= pt.y && pt.y < (clientArea.y + table.getHeaderHeight());
				table.setMenu(header ? headerMenu : tableMenu);
			}
		});
		
		/* IMPORTANT: Dispose the menus (only the current menu, set with setMenu(), will be automatically disposed) */
		table.addListener(SWT.Dispose, new Listener() {
			@Override
			public void handleEvent(Event event) {
				headerMenu.dispose();
//				tableMenu.dispose();
			}
		});
		
		viewer.setContentProvider(new ArrayContentProvider());
		// Get the content for the viewer, setInput will call getElements in the
		// contentProvider
		viewer.setInput(((AccountEditorInput) getEditorInput()).getAccount().getTransactions());
		// Make the selection available to other views
		getSite().setSelectionProvider(viewer);
		// Set the sorter for the table

		// Layout the viewer
		GridData gridData = new GridData();
		gridData.verticalAlignment = GridData.FILL;
		gridData.horizontalSpan = 2;
		gridData.grabExcessHorizontalSpace = true;
		gridData.grabExcessVerticalSpace = true;
		gridData.horizontalAlignment = GridData.FILL;
		viewer.getControl().setLayoutData(gridData);
		
		comparator = new MyViewerComparator();
		viewer.setComparator(comparator);
		
		filter = new CategoryFilter();
		viewer.addFilter(filter);
		
		final Text searchText = new Text(form.getBody(), SWT.BORDER | SWT.SEARCH);
		searchText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
				| GridData.HORIZONTAL_ALIGN_FILL));
		searchText.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent ke) {
				if (ke.keyCode == SWT.ESC)
					searchText.setText("");
				filter.setSearchText(searchText.getText());
				viewer.refresh();
			}
		});
	}

	private void initTableMenu() {
		tableMenu = new Menu(getSite().getWorkbenchWindow().getShell(), SWT.POP_UP);
		MenuItem item = new MenuItem(tableMenu, SWT.PUSH);
		item.setText("Open");
		item = new MenuItem(tableMenu, SWT.PUSH);
		item.setText("Open With");
		new MenuItem(tableMenu, SWT.SEPARATOR);
		item = new MenuItem(tableMenu, SWT.PUSH);
		item.setText("Cut");
		item = new MenuItem(tableMenu, SWT.PUSH);
		item.setText("Copy");
		item = new MenuItem(tableMenu, SWT.PUSH);
		item.setText("Paste");
		new MenuItem(tableMenu, SWT.SEPARATOR);
		item = new MenuItem(tableMenu, SWT.PUSH);
		item.setText("Delete");
	}

	private void createColumns(final Composite parent, final TableViewer viewer) {
		headerMenu = new Menu(parent.getShell(), SWT.POP_UP);
		
		String[] titles = { "", "Category", "Amount", "Date"};
		int[] bounds = { 25, 100, 100, 100};

		TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0], 0);
		col.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				return null;
			}
			@Override
			public Image getImage(Object element) {
				if (((Transaction) element).isIncome()) {
					return AbstractUIPlugin.imageDescriptorFromPlugin(
							Application.PLUGIN_ID, Icons.INCOME).createImage();
				} else {
					return AbstractUIPlugin.imageDescriptorFromPlugin(
							Application.PLUGIN_ID, Icons.EXPENSE).createImage();
				}
			}
		});
//		col.setEditingSupport(new NameEditingSupport(viewer));

		col = createTableViewerColumn(titles[1], bounds[1], 1);
		col.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				Transaction t = (Transaction) element;
				return t.getCategory().getName();
			}
		});
		
		col = createTableViewerColumn(titles[2], bounds[2], 2);
		col.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				Transaction p = (Transaction) element;
				return p.getAmount().toString();
			}
			
			@Override
			public Image getImage(Object element) {
//				if (((Transaction) element).getCategory() == 1) {
//					return null;
//				} else {
					return null;
//				}
			}
		});
		
		col = createTableViewerColumn(titles[3], bounds[3], 3);
		col.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				Transaction t = (Transaction) element;
				return DateUtils.dateToString(t.getDate());
			}
		});
		
	}

	private TableViewerColumn createTableViewerColumn(String title, int bound, final int colNumber) {
		final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
				SWT.NONE);
		final TableColumn column = viewerColumn.getColumn();
		column.setText(title);
		column.setWidth(bound);
		column.setResizable(true);
		column.setMoveable(true);
		column.addSelectionListener(getSelectionAdapter(column, colNumber));
		createMenuItem(headerMenu, column);
		return viewerColumn;

	}
	
	private void createMenuItem(Menu parent, final TableColumn column) {
		final MenuItem itemName = new MenuItem(parent, SWT.CHECK);
		itemName.setText(column.getText());
		itemName.setSelection(column.getResizable());
		itemName.addListener(SWT.Selection, new Listener() {
			@Override
			public void handleEvent(Event event) {
				if (itemName.getSelection()) {
					column.setWidth(150);
					column.setResizable(true);
				} else {
					column.setWidth(0);
					column.setResizable(false);
				}
			}
		});
	}


	@Override
	public void setFocus() {
		viewer.getControl().setFocus();
	}

	public Control fillHorz(Control ctrl) {
		GridData gd = gridData(ctrl);

		gd.horizontalAlignment = SWT.FILL;
		gd.grabExcessHorizontalSpace = true;

		return ctrl;
	}

	public static GridData gridData(Control ctrl) {
		GridData gd;
		if (ctrl.getLayoutData() instanceof GridData) {
			gd = (GridData) ctrl.getLayoutData();
		} else {
			gd = new GridData();
			ctrl.setLayoutData(gd);
		}
		return gd;
	}
	
	private SelectionAdapter getSelectionAdapter(final TableColumn column,
			final int index) {
		SelectionAdapter selectionAdapter = new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				comparator.setColumn(index);
				int dir = comparator.getDirection();
				viewer.getTable().setSortDirection(dir);
				viewer.refresh();
			}
		};
		return selectionAdapter;
	}

	public TableViewer getViewer() {
		return viewer;
	}
	
}
